﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using FlickrNet;
using Google.GData.Photos;
using Google.GData.Client;
using Google.GData.Extensions;
using Google.GData.Extensions.Location;

namespace ClubWebsite
{
    public class GalleryItem
    {
        private string _id;
        public string ID
        {
            get
            {
                return _id;
            }
        }

        private string _title;
        public string Title
        {
            get
            {
                return _title;
            }
        }

        private string _thumbnailURL;
        public string ThumbnailURL
        {
            get
            {
                return _thumbnailURL;
            }
        }

        private string _url;
        public string URL
        {
            get
            {
                return _url;
            }
        }

        public GalleryItem(string id, string title, string thumbnailURL, string url)
        {
            _id = id;
            _title = title;
            _thumbnailURL = thumbnailURL;
            _url = url;
        }

        
    }

    public interface IGallery : IDisposable
    {
        GalleryItem[] GetItems(string tag, string user, int page, int perPage);
        int GetCount(string tag, string user);
    }

    public class FlickrGallery : IGallery
    {
        #region Class variables
        private bool _disposed;
        private Flickr _flickr;
        #endregion

        #region Constructors
        public FlickrGallery(string apiKey)
        {
            _flickr = new Flickr(apiKey);
        }
        #endregion

        #region Public methods
        public GalleryItem[] GetItems(string tag, string user, int page, int perPage)
        {
            // Get the user ID of the given user name.
            string userID = GetUserID(user);
            if (userID == null)
            {
                return new GalleryItem[0];
            }

            // Get a collection of the photos.
            PhotoSearchOptions searchOptions = new PhotoSearchOptions();
            searchOptions.Tags = tag;
            searchOptions.UserId = userID;
            searchOptions.Page = page;
            searchOptions.PerPage = perPage;
            searchOptions.SortOrder = PhotoSearchSortOrder.DateTakenAsc;
            Photos photos = _flickr.PhotosSearch(searchOptions);

            // Return the photo collection.
            return photos.PhotoCollection.ToGalleryItemArray();
        }

        public int GetCount(string tag, string user)
        {
            // Get the user ID of the given user name.
            string userID = GetUserID(user);
            if (userID == null)
            {
                return 0;
            }

            // Get a collection of the photos.
            PhotoSearchOptions searchOptions = new PhotoSearchOptions();
            searchOptions.Tags = tag;
            searchOptions.UserId = userID;
            searchOptions.PerPage = 1;
            Photos photos = _flickr.PhotosSearch(searchOptions);

            // Return the number of photos.
            return photos.TotalPhotos <= (long)int.MaxValue ? (int)photos.TotalPhotos : int.MaxValue;
        }
        #endregion

        #region Helper methods
        /// <summary>
        /// Gets the ID of the specified user.
        /// </summary>
        private string GetUserID(string userName)
        {
            FoundUser user = _flickr.PeopleFindByUsername(userName);
            if (user == null)
            {
                throw new ArgumentException(String.Format("Flickr user ({0}) not found.", userName));
            }
            return user.UserId;
        }
        #endregion

        #region Dispose methods
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        private void Dispose(bool disposing)
        {
            if (!_disposed)
            {
                if (disposing)
                {
                    _flickr = null;
                }
            }
            _disposed = true;
        }
        #endregion
    }

    public class PicasaGallery : IGallery
    {
        #region Class variables
        private bool _disposed;
        #endregion

        #region Constructors
        public PicasaGallery(string dummy)
        {
        }
        #endregion

        #region Public methods
        public GalleryItem[] GetItems(string tag, string user, int page, int perPage)
        {
            // Get a collection of the photos.
            PhotoQuery query = new PhotoQuery(PicasaQuery.CreatePicasaUri(user));
            query.Tags = tag;
            query.NumberToRetrieve = perPage;
            query.StartIndex = (page-1) * perPage;
            query.ExtraParameters = "imgmax=720";

            PicasaService service = new PicasaService("EveryonesClub");
            
            PicasaFeed feed = service.Query(query);
            

            // Return the photo collection.
            return feed.ToGalleryItemArray();
        }

        public int GetCount(string tag, string user)
        {
            // Get a collection of the photos.
            PhotoQuery query = new PhotoQuery(PicasaQuery.CreatePicasaUri(user));
            query.Tags = tag;
            PicasaService service = new PicasaService("EveryonesClub");
            PicasaFeed feed = service.Query(query);
            
            // Return the number of photos.
            return feed.Entries.Count;
        }
        #endregion

        #region Dispose methods
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        private void Dispose(bool disposing)
        {
            if (!_disposed)
            {
                if (disposing)
                {
                }
            }
            _disposed = true;
        }
        #endregion
    }

    public static class ExtensionMethods
    {
        public static GalleryItem[] ToGalleryItemArray(this PhotoCollection photos)
        {
            return photos
                .Cast<Photo>()
                .Select(item => new GalleryItem(item.PhotoId, item.Title, item.SquareThumbnailUrl, item.MediumUrl))
                .ToArray();
        }

        public static GalleryItem[] ToGalleryItemArray(this PicasaFeed feed)
        {
            return feed.Entries
                .Cast<PicasaEntry>()
                .Select(entry => new { Entry = entry, Photo = new PhotoAccessor(entry) })
                .Select(item => new GalleryItem(item.Photo.Id, item.Photo.PhotoTitle, item.Entry.Media.Thumbnails[0].Url, item.Entry.Media.Content.Url))
                .ToArray();
        }
    }
}
